package com.oss.service.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.oss.base.baseconst.ConfigConst;

public class OssSTSService {

	// 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
	public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
	// 当前 STS API 版本
	public static final String STS_API_VERSION = "2015-04-01";

	public AssumeRoleResponse assumeRole(String accessKeyId,
			String accessKeySecret, String roleArn, String roleSessionName,
			String policy, ProtocolType protocolType) throws ClientException {
		try {
			// 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
			IClientProfile profile = DefaultProfile.getProfile(
					REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
			DefaultAcsClient client = new DefaultAcsClient(profile);
			
			// 创建一个 AssumeRoleRequest 并设置请求参数
			final AssumeRoleRequest request = new AssumeRoleRequest();
//			request.setVersion(STS_API_VERSION);
//			request.setMethod(method);
//			request.setProtocol(protocolType);

			request.setRoleArn(roleArn);
			request.setRoleSessionName(roleSessionName);
			request.setPolicy(policy);
			// 发起请求，并得到response
			final AssumeRoleResponse response = client.getAcsResponse(request);

			return response;
		} catch (ClientException e) {
			throw e;
		}
	}

	public AssumeRoleResponse getSTS() {
		// 只有 RAM用户（子账号）才能调用 AssumeRole 接口
		// 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
		// 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
		String accessKeyId = ConfigConst.TESTOSS_ACCID;
		String accessKeySecret = ConfigConst.TESTOSS_ACCSECRET;

		// AssumeRole API 请求参数: RoleArn, RoleSessionName, Polciy, and
		// DurationSeconds

		// RoleArn 需要在 RAM 控制台上获取
//		String roleArn = ConfigConst.ROLE_READYONLY;
		String roleArn = ConfigConst.ROLE_WRITEONLY;

		// RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
		// 但是注意RoleSessionName的长度和规则，不要有空格，只能有'-' '_' 字母和数字等字符
		// 具体规则请参考API文档中的格式要求
		String roleSessionName = "alice-001";

		// 如何定制你的policy?
		String policy = "{\n" + "    \"Version\": \"1\", \n"
				+ "    \"Statement\": [\n" + "        {\n"
				+ "            \"Action\": [\n"
				+ "                \"oss:PutObject\" \n" + "            ], \n"
				+ "            \"Resource\": [\n"
				//如policy指定为LOG,则不能访问public
//				+ "                \"acs:oss:*:*:testofwjt/LOG/*\"\n" + "            ], \n"
				+ "                \"acs:oss:*:*:testofwjt/*\"\n" + "            ], \n"
				+ "            \"Effect\": \"Allow\"\n" + "        }\n"
				+ "    ]\n" + "}";
System.out.println(policy);
		// 此处必须为 HTTPS
		ProtocolType protocolType = ProtocolType.HTTPS;

		try {
			final AssumeRoleResponse response = new OssSTSService().assumeRole(
					accessKeyId, accessKeySecret, roleArn, roleSessionName,
					policy, protocolType);

			System.out.println("Expiration: "
					+ response.getCredentials().getExpiration());
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
			df.setTimeZone(TimeZone.getTimeZone("UTC"));
			System.out.println(df.parse(response.getCredentials().getExpiration()).toString());

			System.out.println("Access Key Id: "
					+ response.getCredentials().getAccessKeyId());
			System.out.println("Access Key Secret: "
					+ response.getCredentials().getAccessKeySecret());
			System.out.println("Security Token: "
					+ response.getCredentials().getSecurityToken());
			return response;
		} catch (ClientException e) {
			System.out.println("Failed to get a token.");
			System.out.println("Error code: " + e.getErrCode());
			System.out.println("Error message: " + e.getErrMsg());
			return null;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	
	public void getBySTS() throws IOException{
		AssumeRoleResponse res = getSTS();
		String accessKeyId = res.getCredentials().getAccessKeyId();
		String accessKeySecret =  res.getCredentials().getAccessKeySecret();
		String securityToken =  res.getCredentials().getSecurityToken();
		OSSClient client = new OSSClient(ConfigConst.ENDPOINT, accessKeyId, accessKeySecret, securityToken);
	
		// 获取Object，返回结果为OSSObject对象,该object为private
		//http://testofwjt.oss-cn-shanghai.aliyuncs.com/public/20160121/oss-java-sdk-21220.txt
		//地址无法直接访问
		OSSObject object = client.getObject(ConfigConst.BUCKETNAME, ConfigConst.KEY+"oss-java-sdk-1999.txt");

		// 获取Object Metadata
		ObjectMetadata metadata = object.getObjectMetadata();

		File file=new File("E:/file.txt");
		BufferedWriter bf=new BufferedWriter(new PrintWriter(file));
		BufferedReader br = new BufferedReader(new InputStreamReader( object.getObjectContent()));
		String tmp = "";
		while((tmp = br.readLine()) != null){
			bf.append(tmp);
		}
		bf.flush();
		bf.close();
		br.close();
		
	}
	
	public void getStsSign(){
		AssumeRoleResponse ossres = new OssSTSService().getSTS();
		try {
		long expireTime = 30;
    	long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
        Date expiration = new Date(expireEndTime);
        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, "/public/20160127/");

        String accessKeyId = ossres.getCredentials().getAccessKeyId();
		String accessKeySecret =  ossres.getCredentials().getAccessKeySecret();
		String securityToken =  ossres.getCredentials().getSecurityToken();
		OSSClient client = new OSSClient(ConfigConst.ENDPOINT, accessKeyId, accessKeySecret, securityToken);
        String postPolicy = client.generatePostPolicy(expiration, policyConds);
        byte[] binaryData;
		binaryData = postPolicy.getBytes("utf-8");
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = client.calculatePostSignature(postPolicy);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}
}
